package com.backend.modules.task.service;

import com.backend.modules.system.entity.SysUser;
import com.backend.modules.task.dto.FileAuditResult;
import com.backend.modules.task.entity.Task;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 邮件服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class EmailService {

    private final JavaMailSender mailSender;
    private final TemplateEngine templateEngine;

    @Value("${spring.mail.username}")
    private String fromEmail;

    @Value("${app.frontend-url:http://localhost:5173}")
    private String frontendUrl;

    /**
     * 发送审核不通过邮件
     */
    @Async
    @Transactional(readOnly = true)
    public void sendAIRejectionEmail(SysUser student, Task task, FileAuditResult auditResult) {
        try {
            // 预先获取所有需要的属性
            String studentEmail = student.getEmail();
            String studentRealName = student.getRealName();
            String studentUsername = student.getUsername();

            // 严格验证邮箱
            if (studentEmail == null || studentEmail.isEmpty() || !isValidEmail(studentEmail)) {
                log.warn("学生邮箱为空或无效，无法发送邮件通知: {}", studentEmail);
                return;
            }
            
            String taskName = task.getName();
            String fileRequirements = task.getFileRequirements();
            String submitRequirements = task.getSubmitRequirements();
            LocalDateTime deadline = task.getDeadline();
            Long taskId = task.getId();
            
            String reason = auditResult.getReason();

            Map<String, Object> variables = new HashMap<>();
            variables.put("studentName", studentRealName);
            variables.put("taskName", taskName);
            variables.put("reason", reason);
            variables.put("suggestions", auditResult.getSuggestions());
            variables.put("fileRequirements", fileRequirements);
            variables.put("submitRequirements", submitRequirements);
            variables.put("deadline", deadline);
            variables.put("systemName", "高校文件收集系统");
            variables.put("submissionUrl", String.format("/student/task/%d/submission", taskId));

            try {
                sendEmail(
                    studentEmail,
                    "【高校文件收集系统】文件格式审核不通过",
                    "email/ai-rejection",
                    variables
                );
                
                log.info("AI审核不通过邮件发送成功: 学生={}, 邮箱={}, 任务={}", 
                    studentUsername, studentEmail, taskName);
            } catch (MessagingException e) {
                log.error("邮件发送失败，可能是邮箱 {} 不存在或无效: {}", studentEmail, e.getMessage());
            }
        } catch (Exception e) {
            log.error("发送AI审核不通过邮件失败", e);
        }
    }

    /**
     * 发送教师审核不通过邮件
     */
    @Async
    @Transactional(readOnly = true)
    public void sendTeacherRejectionEmail(SysUser student, Task task, String reason) {
        try {
            // 预先获取所有需要的属性
            String studentEmail = student.getEmail();
            String studentRealName = student.getRealName();
            String studentUsername = student.getUsername();
            
            // 严格验证邮箱
            if (studentEmail == null || studentEmail.isEmpty() || !isValidEmail(studentEmail)) {
                log.warn("学生邮箱为空或无效，无法发送邮件通知: {}", studentEmail);
                return;
            }
            
            String taskName = task.getName();
            LocalDateTime deadline = task.getDeadline();
            Long taskId = task.getId();
            
            // 获取教师名称，处理可能的懒加载
            String teacherName = "教师";
            try {
                if (task.getTeacher() != null) {
                    teacherName = task.getTeacher().getRealName();
                }
            } catch (Exception e) {
                log.warn("获取教师姓名失败", e);
            }

            Map<String, Object> variables = new HashMap<>();
            variables.put("studentName", studentRealName);
            variables.put("taskName", taskName);
            variables.put("reason", reason);
            variables.put("teacherName", teacherName);
            variables.put("deadline", deadline);
            variables.put("systemName", "高校文件收集系统");
            variables.put("submissionUrl", String.format("/student/task/%d/submission", taskId));

            try {
                sendEmail(
                    studentEmail,
                    "【高校文件收集系统】提交审核不通过",
                    "email/teacher-rejection",
                    variables
                );
                
                log.info("教师审核不通过邮件发送成功: 学生={}, 邮箱={}, 任务={}", 
                    studentUsername, studentEmail, taskName);
            } catch (MessagingException e) {
                log.error("邮件发送失败，可能是邮箱 {} 不存在或无效: {}", studentEmail, e.getMessage());
            }
        } catch (Exception e) {
            log.error("发送教师审核不通过邮件失败", e);
        }
    }

    /**
     * 发送任务截止提醒邮件
     */
    @Async
    @Transactional(readOnly = true)
    public void sendDeadlineReminderEmail(SysUser student, Task task, String timeLeft) {
        try {
            // 预先获取所有需要的属性
            String studentEmail = student.getEmail();
            String studentRealName = student.getRealName();
            String studentUsername = student.getUsername();
            
            // 严格验证邮箱
            if (studentEmail == null || studentEmail.isEmpty() || !isValidEmail(studentEmail)) {
                log.warn("学生邮箱为空或无效，无法发送截止提醒邮件: {}", studentEmail);
                return;
            }
            
            String taskName = task.getName();
            String fileRequirements = task.getFileRequirements();
            String submitRequirements = task.getSubmitRequirements();
            LocalDateTime deadline = task.getDeadline();
            Long taskId = task.getId();

            // 构建完整的URL
            String submissionUrl = String.format("%s/student/task/%d/submission", frontendUrl, taskId);

            Map<String, Object> variables = new HashMap<>();
            variables.put("studentName", studentRealName);
            variables.put("taskName", taskName);
            variables.put("timeLeft", timeLeft);
            variables.put("fileRequirements", fileRequirements);
            variables.put("submitRequirements", submitRequirements);
            variables.put("deadline", Date.from(deadline.atZone(ZoneId.systemDefault()).toInstant()));
            variables.put("systemName", "高校文件收集系统");
            variables.put("submissionUrl", submissionUrl);
            variables.put("date", new Date());

            try {
                sendEmail(
                    studentEmail,
                    "【高校文件收集系统】任务即将截止提醒",
                    "email/deadline-reminder",
                    variables
                );
                
                log.info("截止提醒邮件发送成功: 学生={}, 邮箱={}, 任务={}", 
                    studentUsername, studentEmail, taskName);
            } catch (MessagingException e) {
                log.error("邮件发送失败，可能是邮箱 {} 不存在或无效: {}", studentEmail, e.getMessage());
            }
        } catch (Exception e) {
            log.error("发送截止提醒邮件失败", e);
        }
    }

    /**
     * 简单验证邮箱格式
     */
    private boolean isValidEmail(String email) {
        if (email == null || email.isEmpty()) {
            return false;
        }
        // 更严格的邮箱格式验证
        String emailRegex = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$";
        return email.matches(emailRegex);
    }

    /**
     * 发送邮件
     */
    private void sendEmail(String to, String subject, String template, Map<String, Object> variables) throws MessagingException {
        if (!isValidEmail(to)) {
            log.error("无效的邮箱地址: {}", to);
            throw new IllegalArgumentException("无效的邮箱地址: " + to);
        }

        variables.put("date", new Date());
        
        Context context = new Context();
        variables.forEach(context::setVariable);
        
        String content = templateEngine.process(template, context);
        
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
        try {
            helper.setFrom(fromEmail);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);
            log.info("开始发送邮件: 收件人={}, 主题={}", to, subject);
            mailSender.send(message);
            log.info("邮件发送成功: 收件人={}, 主题={}", to, subject);
        } catch (MessagingException e) {
            String errorMsg = e.getMessage();
            if (errorMsg.contains("550") || errorMsg.contains("non-existent account")) {
                log.error("邮件发送失败: 收件人邮箱不存在 {}", to);
                throw new IllegalArgumentException("收件人邮箱不存在: " + to);
            } else {
                log.error("邮件发送失败: 收件人={}, 主题={}, 错误={}", to, subject, errorMsg);
                throw e;
            }
        }
    }
} 